package com.qqt.csr.im.service.sensitiveword;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.houbb.sensitive.word.api.IWordTag;
import com.google.common.collect.Sets;
import com.qqt.csr.im.entity.SensitiveWord;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SensitiveWordTagService implements IWordTag {
    /**
     * 本地缓存单词标签信息，key:敏感词
     */
    private Cache<String, Set<String>> SW_TAG_CACHE = Caffeine.newBuilder()
            .maximumSize(200000)
            .expireAfterWrite(1, TimeUnit.DAYS)
            .build();
    /**
     * 标签格式:租户id|词库id
     */
    private final String tagFormat = "%s|%s";

    @Autowired
    private SensitiveWordService sensitiveWordService;

    @Override
    public Set<String> getTag(String word) {
        return SW_TAG_CACHE.get(word, key -> {
            List<SensitiveWord> sWordList = sensitiveWordService.getWorldListForTag(key);
            if (CollectionUtils.isEmpty(sWordList)) {
                return Set.of();
            }

            return sWordList.stream()
                    .map(sw -> String.format(tagFormat, sw.getTenantId(), sw.getRepoId()))
                    .collect(Collectors.toSet());
        });
    }

    /**
     * 添加标签
     *
     * @param word
     * @param tenantId
     * @param repoId
     */
    public synchronized void addTag(String word, String tenantId, Long repoId) {
        Optional.ofNullable(SW_TAG_CACHE.getIfPresent(word)).ifPresent(set -> {
            String newTag = String.format(tagFormat, tenantId, repoId);
            if(set.contains(newTag)){
                return;
            }
            Set<String> copyTagSet = Sets.newHashSet(set);
            copyTagSet.add(newTag);
            SW_TAG_CACHE.put(word, copyTagSet);
        });
    }
}
